<?php
/**
 * I-Cafe framework
 * 
 * @category CF
 * @package CF_View
 * @link http://www.i-cafe.org
 * @license http://www.i-cafe.org/license
 * @version 04-04-2010
 * @author tcl_java@yahoo.com
 */

abstract class CF_View_Abstract extends CF_Component
{
	/**
	 * 
	 * @var string
	 */
	protected $_path = '';
	
	/**
	 * 
	 * @var string
	 */
	protected $_file = '';
	
	/**
	 * 
	 * @var string
	 */
	protected $_extension = '';
	
	/**
	 * 
	 * @var CF_Reader_Array
	 */
	protected $_vars;
	
	/**
	 * 
	 * @var boolean
	 */
	protected $_resetOnRender = true;
	
	/**
	 * 
	 */
	public function __construct()
	{
		# notify before construct event
		$this->fireEvent('beforeconstruct', array($this));
		
		# register event
		$this->addEvents(
			'beforeassign',
			'assign',
			'beforerender',
			'render',
			'beforedisplay',
			'display'
		);
		
		$this->_vars = new CF_Storage_Array();
		
		# notify construct event
		$this->fireEvent('construct', array($this));
	}
	
	public function getPath()
	{
		return $this->_path;
	}
	
	/**
	 * 
	 * @param string $path
	 * @return CF_View_Abstract $this
	 * @throws CF_View_Exception
	 */
	public function setPath($path)
	{
		if(!is_dir($path)){
			throw new CF_View_Exception('View path does not exists.');
		}
		
		$this->_path = $path;
		return $this;
	}
	
	/**
	 * @return string
	 */
	public function getFile()
	{
		return $this->_file;
	}
	
	/**
	 * 
	 * @param string $file
	 * @return CF_View_Abstract $this
	 * @throws CF_View_Exception
	 */
	public function setFile($file)
	{
		$filePath = $this->_path . $file . '.' . $this->_extension;
		if(!is_file($filePath)){
			throw new CF_View_Exception("View file \"$filePath\" does not exists");
		}
		
		$this->_file = $file;
		return $this;
	}
	
	/**
	 * @return string
	 */
	public function getScriptExtension()
	{
		return $this->_extension;
	}
	
	/**
	 * 
	 * @param string $ext
	 * @return CF_View_Abstract $this
	 */
	public function setScriptExtension($ext)
	{
		$this->_extension = (string) $ext;
		return $this;
	}
	
	/**
	 * 
	 * @param boolean $bol
	 * @return CF_View_Abstract $this
	 */
	public function resetOnRender($bol)
	{
		$this->_resetOnRender = (boolean) $bol;
		return $this;
	}
	
	/**
	 * 
	 * @param array $data
	 * @return CF_View_Abstract $this
	 */
	public function vars(array $data)
	{
		$this->_vars = new CF_Storage_Array($data);
		return $this;
	}
	
	/**
	 * @return array
	 */
	public function getVars()
	{
		return $this->_vars;
	}
	
	/**
	 * 
	 * @param string|array $name
	 * @param mixed $value
	 * @return CF_View_Abstract $this
	 */
	public function assign($name, $value = null)
	{
		# fire before assign event
		if(CF_Observable::VALUE_RETURN === $this->fireEvent('beforeassign', array($this, &$name, $value))) return;
		
		if(is_array($name)){
			foreach ($name as $k => $v) {
				$this->_vars->set($k, $v);
			}
		}else{
			$this->_vars->set($name, $value);
		}
		
		# fire assign event
		$this->fireEvent('assign', array($this, &$name, $value));
			
		return $this;
	}
	
	/**
	 * 
	 * @param string $file
	 * @param string $path
	 * @return string
	 */
	public function getViewFile()
	{
		return $this->_path . $this->_file . '.' . $this->_extension;
	}
	
	/**
	 * 
	 * @param string $file
	 * @param string $path
	 */
	public function display()
	{
		# fire before display event
		if(CF_Observable::VALUE_RETURN === $this->fireEvent('beforedisplay', array($this))) return;
		
		# out
		echo $this->render();
		
		# fire display event
		$this->fireEvent('display', array($this));
	}
	
	/**
	 * 
	 * @param string $file
	 * @param string $path
	 */
	abstract function render();
}